iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Software Development

你知道Go是什麼嗎?系列 第 8

Day8 - 常見結構 - Golang

  • 分享至 

  • xImage
  •  

來到第八天,今天介紹常見結構,明天介紹流程控制,基礎的部分就告一段落了(灑花)。基本上大部分學校的程式課都指教到這邊,學校的課通過了,但其實什麼都不會,出去也找不到工作...扯太遠了。總之今天就先來介紹一些常見結構吧owo

陣列(array)

陣列是線性且同質的資料結構,使用零或正整數為索引來存取其中元素,陣列內元素必須是同一型態,因此在宣告時就得先定義好。宣告後陣列長度就不可變更了

宣告陣列

格式如下
var arrayName [n]type

以下範例以string陣列為例

var langs [4]string //宣告一個長度為4,型態為string的陣列
	
langs[0] = "Go"
langs[1] = "Python"
langs[2] = "Ruby"
langs[3] = "PHP"

fmt.Println(langs) //[Go Python Ruby PHP]
langs := [4]string{
    "Go",
    "Python",
    "Ruby",
    "PHP",
}
fmt.Println(langs) //[Go Python Ruby PHP]

宣告時也可使用取代長度,編譯器會依照初始值的數量,建立一個陣列

langs := [...]string{
    "Go",
    "Python",
    "Ruby",
    "PHP",
}

fmt.Println(len(langs)) // 4

訪問陣列

與大部分陣列一樣,直接 array[index] 就可訪問陣列內指定位置之值,而若要走訪全部陣列,可使用for搭配range走訪相關結構

for i, v := range pow {
    fmt.Println("index:",i,"value:",v)
}

output:

index: 0 value: Go
index: 1 value: Python
index: 2 value: Ruby
index: 3 value: PHP

  • i:index,序列
  • v:value,陣列中當個序列的值

若不需要用到iv,也可使用 _ 取代,用法如下

for i, _ := range langs

for _, value := range langs

切片(slice)

陣列宣告後長度就不可變更了,而Go提供slice這種容器,與陣列相似,但可以擴增長度

宣告切片

// 方式一:建立一個帶有資料的 string slice
// 適合用在知道 slice 裡面的元素有哪些時
people := []string{"Aaron", "Jim", "Bob", "Ken"}
fmt.Println(people) //[Aaron Jim Bob Ken]

// 方式二:透過 make 可以建立「空 slice」
// 適合用會對 slice 中特定位置元素進行操作時
people := make([]int, 4)  // len=4 cap=4,[0,0,0,0]
fmt.Println(people) //[0 0 0 0]

// 方式三:空的 slice,一般會搭配 append 使用
var people []string
people = append(people, "Aaron")
people = append(people, "Jim")
fmt.Println(people) // [Aaron Jim]

// 方式四:大該知道需要多少元素時使用,搭配 append 使用
people := make([]string, 0, 5) // len=0 cap=5, []
people = append(people, "Aaron")
people = append(people, "Jim")
fmt.Println(people) // [Aaron Jim]

一般會先建立一個陣列,再取得陣列內指定元素建立切片

// 宣告字串陣列,並且初始化 5 個名稱
arr := [5]string{"Furry", "Mark", "Ben", "Morris", "Wayne"}

// 建立字串切片,並且取得arr陣列的第 1 個到第 3 個元素
slice := arr[1:4]

// 印出切片元素
for _, v := range slice {
    fmt.Print(v, " ") // Mark Ben Morris 
}

上面這是切片的基本用法,切片其實是指向原本的陣列,因此print切片內容時其實是印出原本陣列內的資料,而對切片修改資料時也是修改原始陣列的資料,為上面程式碼加入下面幾行來進行測試,可以看到更改slice內的資料,arr的資料也一併被改變了。

slice[2] = "Changeeeee"

for _, v := range arr {
    fmt.Print(v, " ") //Furry Mark Ben Changeeeee Wayne
}

動態建立切片

我們也可以用 make() 動態建立一個切片,建立時可以指定長度和容量,格式有以下兩種:

// 建立一個len與cap都為2的slice
make([]int, 2)

// 建立一個len為2 cap為4的slice
make([]int, 2, 4)

切片擴增

當切片之length不夠時,可使用append函式將切片擴增,以下為範例

slice := make([]string, 0) //宣告一長度為0的slice

slice = append(slice, "Test") //使用append加入元素
fmt.Println(slice) // [Test]

slice更詳細介紹可以參考參考資料中別的前輩介紹,我這邊稍微介紹而已,記憶體的部分沒有解釋太多

映射(map)

Map,又稱字典(Dictionary)是一個抽象的資料結構,它包含著類似於(鍵,值)的有序對。

宣告map

// 第一種方式,建立一個型別為 map 的變數,其中的
// key值是string,value也是string
colors := map[string]string{}
// 也可以直接帶值
colors := map[string]string{
    "1": "red",
    "2": "orenge",
    "3": "yellow",
}

// 第二種方式,最正統的使用var宣告
var colors map[string]string

// 第三種方式,使用 make 建立 Map。
// Key 的型別是 string,Value 是 int
colors := make(map[string]int)
colors["red"] = 10
fmt.Println(colors) // map[red:10]

存取資料

存取方式與array相似,透過[]來存取資料,也與陣列一樣可以使用len()函數來看存了多少筆資料

colors := map[string]string{
    "1": "red",
    "2": "orenge",
    "3": "yellow",
}
	
fmt.Println(colors["1"]) //  red
fmt.Println(colors["2"]) //  orenge
fmt.Println(colors["3"]) //  yellow
fmt.Println("map's length: ", len(colors)) // map's length:  3

新增、刪除

新增使用[]直接加入值

刪除使用delete(map, key)來刪除map內鍵值為key的資料

colors["4"] = "green" //新增第四筆資料
delete(colors, "3")   //刪除key是3的資料

for k, v := range colors {
    fmt.Println(k, ": ", v)
}
// 1 :  red
// 2 :  orenge
// 4 :  green

確認存在與否

可以使用以下方法直接測試map中是否有key
elem, ok := m[key]

  • 有值:elem=valueok=true
  • 無值:elem="",ok=false
value, isExist := colors["1"] // red, true
value2, isExist2 := colors["5"] // "", false

今天介紹的滿普通的,就介紹些結構而已,但後面會持續用到這幾個結構,算是很基礎的東西吧,多用就習慣了。

參考資料

tour of Go:
https://go.dev/tour/list

[Golang] Slice and Array:
https://pjchender.dev/golang/slice-and-array/


上一篇
Day7 - Pointer - Golang
下一篇
Day9 - 流程控制 - Golang
系列文
你知道Go是什麼嗎?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言